<?php


namespace app\service\model;


use app\service\exception\ParameterException;
use app\service\Y;
use think\Exception;
use think\facade\Db;
use think\Model;

class GoodsModel extends BaseModel
{

    protected $table = 'goods';

    /**
     * 关联分类
     * @return \think\model\relation\BelongsTo
     */
    public function category(): \think\model\relation\BelongsTo
    {
        return $this->belongsTo(CategoryModel::class, 'category_id', 'id');
    }

    /**
     * 关联详情
     * @return \think\model\relation\HasOne
     */
    public function content(): \think\model\relation\HasOne
    {
        return $this->hasOne(GoodsContentModel::class, 'goods_id', 'id');
    }

    /**
     * 关联图片
     * @return \think\model\relation\HasMany
     */
    public function images(): \think\model\relation\HasMany
    {
        return $this->hasMany(GoodsImagesModel::class, 'goods_id', 'id')
            ->order('sort', 'desc')
            ->order('id', 'desc');
    }

    /**
     * 关联sku
     * @return \think\model\relation\HasMany
     */
    public function sku(): \think\model\relation\HasMany
    {
        return $this->hasMany(GoodsSkuModel::class, 'goods_id', 'id');
    }

    /**
     * 保存商品数据
     * @param $param
     * @param $id
     * @return \think\response\Json
     * @throws ParameterException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function saveGoods($param, $id)
    {

        if ($id > 0) {
            $goods = self::find($id);
            if (!$goods) {
                throw new ParameterException(['msg' => '商品不存在']);
            }
            $check_data = self::where('name', '=', $param['name'])->where('id', '<>', $id)->find();
        } else{
            $check_data = self::where('name', '=', $param['name'])->find();
            $goods = new self();
        }

        if ($check_data) {
            throw new ParameterException(['msg' => '商品名称已存在']);
        }

        Db::startTrans();
        try {
            // 保存商品数据
            $goods->save($param);

            $old_unlink_images = [];

            // 删除并重新添加商品图片
            $images = input('param.pc_src/a', []);
            $old_images = GoodsImagesModel::where('goods_id', '=', $goods->id)->column('image');
            foreach ($old_images as $oi) {
                if (!in_array($oi, $images)) $old_unlink_images[] = $oi;
            }

            GoodsImagesModel::where('goods_id', '=', $goods->id)->delete();
            $img_data = [];
            foreach ($images as $image) {
                $image = event('image_storage', ['image' => $image, 'type' => 'goods'], 'true');
                $img_data[] = [
                    'goods_id' => $goods->id,
                    'image' => $image
                ];
            }
            $img_data && (new GoodsImagesModel())->insertAll($img_data);

            // 保存商品详情
            // 匹配获取详情中的图片
            $preg = '/<img.*?src=[\"|\']?(.*?)[\"|\']?\s.*?>/i';
            preg_match_all($preg, $param['content'], $allImg); //这里匹配所有的img
            $img = [];
            foreach ($allImg[1] as $image) {
                if (!strpos($image, '-big.jpg')) {
                    $img[] = str_replace('.jpg', '-big.jpg', event('image_storage', ['image' => $image, 'type' => 'goods'], 'true'));
                } else {
                    $img[] = $image;
                }
            }
            $param['content'] = str_replace($allImg[1], $img, $param['content']);

            $goods_content = GoodsContentModel::where('goods_id', '=', $goods->id)->find();
            if ($goods_content) {
                // 匹配原有详情内容中的图片
                preg_match_all($preg, $goods_content->content, $oldAllImg);
                // 内容添加完成后删除旧图片
                foreach ($oldAllImg as $oi) {
                    if (!in_array($oi, $allImg)) {
                        $old_unlink_images[] = $oi;
                    }
                }

                $goods_content->content = $param['content'];
                $goods_content->save();

            } else {
                GoodsContentModel::create([
                    'goods_id' => $goods->id,
                    'content' => $param['content']
                ]);
            }

            if ($param["type"] == 2) {
                // 处理规格
                $attr = json_decode(input('param.attr', ''), true);

                $old_images = GoodsSkuModel::where('goods_id', '=', $goods->id)->column('image');

                GoodsSkuModel::where('goods_id', '=', $goods->id)->delete();
                $attr_data = $sku_images = [];
                foreach ($attr as $v) {
                    if ($v[1] || $v[2]) {
                        $image = '';
                        if ($v[2] && $v[2] != '/static/image/default.jpg') {
                            $sku_images[] = $image = event('image_storage', ['image' => $v[2], 'type' => 'goods'], 'true');
                        }
                        $attr_data[] = [
                            'goods_id' => $goods->id,
                            'attrs' => $v[0],
                            'price' => $v[1],
                            'image' => $image,
                        ];
                    }
                }
                if (!$attr_data) {
                    throw new Exception('多规格商品，请至少设置一组规格数据');
                }

                foreach ($old_images as $oi) {
                    if (!in_array($oi, $sku_images)) $old_unlink_images[] = $oi;
                }

                (new GoodsSkuModel())->insertAll($attr_data);
            }

            Db::commit();

            // 删除旧图
            unlink_old_image($old_unlink_images);

            return Y::success([], '保存成功');
        } catch (Exception $e) {
            Db::rollback();
            return Y::error($e->getMessage());
        }
    }
}